package fag.core.game.test.playground.solid;

import java.awt.Color;

import fag.core.collision.Hitbox;
import fag.core.game.test.playground.AbstractPlaygroundDoodad;
import fag.core.geometry.Vector2D;

/**
 * Classe des solides de la scène.
 * @author lumz
 */
public abstract class AbstractSolid extends AbstractPlaygroundDoodad {

	public static final Vector2D GRAVITY = new Vector2D(0, 980);
	
	protected static final Color OUTLINE_COLOR = Color.DARK_GRAY;
	
	private static final float[] LUMINOSITY_RANGE = {(float) 0.5, (float) 0.95};
	
	// Physique
	private double angularVelocity = 0;
	private Vector2D linearVelocity = new Vector2D();
	private double mass = 10;
	private double momentOfInertia = 10;
	private double elasticity = 0.2;
	
	// Affichage
	protected Color color = null;
	
	/**
	 * Constructeur par défaut.
	 * @param hitbox
	 */
	public AbstractSolid(Hitbox hitbox) {
		super(hitbox);
		
		initializeColor();
	}
	
	/**
	 * Accesseur de la vitesse angulaire.
	 * @return 0 si le solide est fixe sinon sa vitesse angulaire.
	 */
	public double getAngularVelocity() {
		return angularVelocity;
	}
	
	/**
	 * Accesseur de l'élasticité.
	 * @return L'élasticité.
	 */
	public double getElasticity() {
		return elasticity;
	}
	
	/**
	 * Accesseur de la vitesse linéaire.
	 * @return 0 si le solide est fixe sinon sa vitesse linéaire.
	 */
	public Vector2D getLinearVelocity() {
		return linearVelocity.clone();
	}
	
	/**
	 * Accesseur de la masse.
	 * @return La masse.
	 */
	public double getMass() {
		return mass;
	}
	
	/**
	 * Accesseur du moment d'inertie.
	 * @return Le moment d'inertie.
	 */
	public double getMomentOfInertia() {
		return momentOfInertia;
	}
	
	/**
	 * Mutateur de la vitesse angulaire.
	 * @param angularVelocity La nouvelle vitesse angulaire.
	 */
	public void setAngularVelocity(double angularVelocity) {
		this.angularVelocity = angularVelocity;
	}
	
	/**
	 * Mutateur de l'élasticité.
	 * @param elasticity La nouvelle élasticité.
	 */
	public void setElasticity(double elasticity) {
		this.elasticity = elasticity;
	}

	/**
	 * Mutateur de la vitesse linéaire.
	 * @param value La nouvelle vitesse linéaire.
	 */
	public void setLinearVelocity(Vector2D value) {
		linearVelocity = value.clone();
	}
	
	/**
	 * Mutateur de la masse.
	 * @param mass La nouvelle masse.
	 */
	public void setMass(double mass) {
		this.mass = mass;
	}
	
	/**
	 * Mutateur du moment d'inertie.
	 * @param momentOfInertia Le nouveau moment d'inertie.
	 */
	public void setMomentOfInertia(double momentOfInertia) {
		this.momentOfInertia = momentOfInertia;
	}
	
	/**
	 * Avancer ce solide dans le temps.
	 * @param dt L'avancement dans le temps.
	 */
	public void step(double dt) {
		
		linearVelocity = linearVelocity.add(GRAVITY.mul(dt));		
		
		translate(linearVelocity.mul(dt), Referential.ABSOLUTE);
		rotate(angularVelocity * dt, getTranslation(), Referential.ABSOLUTE);
	}
	
	/**
	 * Sélectionner une couleur aléatoire. 
	 */
	private void initializeColor() {
		
		float min = LUMINOSITY_RANGE[0];
		float max = LUMINOSITY_RANGE[1];
		float range = max - min;
		
		color = new Color((float)(Math.random() * range + min), (float)(Math.random() * range + min), (float)(Math.random() * range + min));
	}
}
